/**
* \file		Caracteristiques.c
* \brief	Code des fonctions du module Caracteristiques
* \details	C'est ici qu'est le code des accesseurs, mutateurs ainsi que
*		la fonction de test vérifant le bon fonctionnement du module
*		Caracteristiques.
*		Une description de la structure Caracteristiques est fournie à
*		la rubrique \link Caracteristiques.h
*/

/* voir si on garde tous les includes */
#include "Caracteristiques.h"

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

/*========================== Gestion de la mémoire ==========================*/

void initCaract(Caracteristiques *pcarac)
{

   pcarac->PV = 0;
   pcarac->minage = 0;
   pcarac->bucheronnage = 0;
   pcarac->artisanat = 0;
   pcarac->faim = 0;

   ajoutePV(pcarac, 130 + rand()%(41));
   pcarac->minage = 0;
   pcarac->bucheronnage = 0;
   pcarac->artisanat = 0;
   ajouteFaim(pcarac, 50 + rand()%(21));
}

void creerCaract(Caracteristiques **pcarac)
{
   *pcarac = (Caracteristiques *)malloc(sizeof(Caracteristiques));
   initCaract(*pcarac);
}

void detruireCaract(Caracteristiques *pcarac)
{
   free(pcarac);
}

/*============================= Accesseurs =============================*/

unsigned int getPV(const Caracteristiques *pcarac)
{
   assert(pcarac->PV <= 200);
   return pcarac->PV;
}

unsigned int getMinage(const Caracteristiques *pcarac)
{
   return pcarac->minage;
}

unsigned int getBucheronnage(const Caracteristiques *pcarac)
{
   return pcarac->bucheronnage;
}

unsigned int getArtisanat(const Caracteristiques *pcarac)
{
   return pcarac->artisanat;
}

unsigned int getFaim(const Caracteristiques *pcarac)
{
   assert(pcarac->faim >=0);
   assert(pcarac->faim <= 100);
   return pcarac->faim;
}


/*============================= Mutateurs =============================*/

void ajoutePV(Caracteristiques *pcarac, int varPV)
{
   if ((int)getPV(pcarac) < -varPV) /* Cast : car sinon, la valeur négative est
				considérée comme un unsigned int et entraîne
				généralement une mise à zéro du nombre de
				points de vie */
	{
	   pcarac->PV = 0;
	}
   else
	{
	   pcarac->PV += varPV;

	   if (pcarac->PV > 200)
		{
		   pcarac->PV = 200;
		}
	
	}

}

void ajouteMinage(Caracteristiques *pcarac, int varMinage)
{
   if ((int)getMinage(pcarac) < -varMinage)
	{
	   pcarac->minage = 0;
	}
   else
	{
	   pcarac->minage += varMinage;

	/* Pour empêcher un dépassement de valeur seuil */
	   if(getMinage(pcarac) >500)
		{
		   pcarac->minage = 500;
		}
	}
}

void ajouteBucheronnage(Caracteristiques *pcarac, int varBucheronnage)
{
   if ((int)getBucheronnage(pcarac) < -varBucheronnage)
	{
	   pcarac->bucheronnage = 0;
	}
   else
	{
	   pcarac->bucheronnage += varBucheronnage;

	   if(getBucheronnage(pcarac) >500)
		{
		   pcarac->bucheronnage = 500;
		}

	}
}

void ajouteArtisanat(Caracteristiques *pcarac, int varArtisanat)
{
   if ((int)getArtisanat(pcarac) < -varArtisanat)
	{
	   pcarac->artisanat = 0;
	}
   else
	{
	   pcarac->artisanat += varArtisanat;

	   if(getArtisanat(pcarac) >500)
		{
		   pcarac->artisanat = 500;
		}

	}
}

void ajouteFaim(Caracteristiques *pcarac, int varFaim)
{
   if ((int)getFaim(pcarac) < -varFaim)
	{
	   pcarac->faim = 0;
	}
   else
	{
	   pcarac->faim += varFaim;
	   if (pcarac->faim > 100)
		{
		   pcarac->faim = 100;
		}
	}
}

/*========================== Fonction de Test ==========================*/

void testCaracteristiques()
{
   Caracteristiques *carac;
   int var[] = {-100, -20, 0, 10, 200};
   int verif = 0;	/* valeur à laquelle comparer les caractéristiques de
			récolte/artisanat */
   int i;


   creerCaract(&carac);

   printf("Test de caractéristiques\n");

   printf("\tInitialisation des Caractéristiques\t\t");
   assert((getPV(carac) >= 130)&&
	   (getPV(carac) <= 170));

   assert((getFaim(carac) >= 50)&&
	   (getFaim(carac) <= 70));

   assert(getMinage(carac) == 0);
   assert(getBucheronnage(carac) == 0);
   assert(getArtisanat(carac) == 0);
   printf("OK\n");

   printf("\tAffectation et récupération de valeurs\t\t");
   for(i=0; i<5; i++)
	{
	   verif += var[i];
	   if(verif < 0)
		{
		   verif = 0;
		}

	   ajoutePV(carac, var[i]);
	   assert((getPV(carac) >= 0)&&
		   (getPV(carac) <= 200));

	   ajouteMinage(carac, var[i]);
	   assert(getMinage(carac) == verif);

	   ajouteBucheronnage(carac, var[i]);
	   assert(getBucheronnage(carac) == verif);

	   ajouteArtisanat(carac, var[i]);
	   assert(getArtisanat(carac) == verif);

	   ajouteFaim(carac, var[i]);
	   assert((getFaim(carac) >= 0)&&
		   (getFaim(carac) <= 100));

	}
	   printf("OK\n");

   printf("\tCas de dépassement de valeur seuil\t\t");
	   ajouteMinage(carac, 1000);
	   assert(getMinage(carac) == 500);

	   ajouteBucheronnage(carac, 1000);
	   assert(getBucheronnage(carac) == 500);

	   ajouteArtisanat(carac, 1000);
	   assert(getArtisanat(carac) == 500);

   printf("OK\n\n");

   detruireCaract(carac);
}
